
#include	"zig/tinyini.hpp"

using namespace zig;

int main() {
	{
		INIFile test("foo.ini", true, false);
		std::cout << "TEST ADDING SOMETHING" << std::endl;
		test["foo"]["bar"] = "baz";
		std::cout << "TESTED ADDING SOMETHING" << std::endl;
	}
	{
		std::cout << "REOPENING" << std::endl;
		const INIFile test("foo.ini", false, true);
		std::cout << "REOPENED" << std::endl;
		std::cout << "FOOBAR:" << test["foo"]["bar"] << std::endl;
		std::cout << "FOO:" << test["foo"] << std::endl;
		std::cout << "FOOBAZ:" << test["foo"]["baz"] << std::endl;
	}
	{
		std::cout << "TEST NO WRITEBACK" << std::endl;
		INIFile test("foo.ini", false, true);
		test["quux"]["spam"] = "ni";
	}
	
	{
		INIFile	test("server.ini", true, false);
		std::cout << "TEST options " << std::endl;
		test["server"]["ip"] = "127.0.0.1";
		test["server"]["port"] = "4344";
		test["server"]["service"] = "tao";
		
		std::cout << "INI Options : ";
		const INIFile::option_t&	options = test.options();
		INIFile::option_t::const_iterator it = options.begin();
		while( it != options.end() ) {
			std::cout << *it << " ";
			++it;
		}
		std::cout << std::endl;

		std::cout << "[ server ] Options : ";
		INISection	section = test[ "server" ];
		const INISection::option_t&	options_s = section.options();
		INISection::option_t::const_iterator it_s = options_s.begin();
		while( it_s != options_s.end() ) {
			std::cout << *it_s << " ";
			++it_s;
		}
		std::cout << std::endl;		
		//for_each( options.begin(), options.end(), std::cout );
	}
	
	return	0;
}

/*
My idea is to create a data structure that represents an INI file. It is a wrapper for a std::map (associative array) which maps section names to "sections", which in turn are data structures mapping property names to values in a similar way. The data structure initializes itself in the constructor by accepting a file name and attempting to read an INI file from it (throwing an exception if anything goes wrong). This is exception-safe because the wrapped data members are standard library containers held by value (not pointer). The destructor may attempt to write to the INI file again (if this behaviour was requested). It does not throw an exception on failure, because you shouldn't do that in destructors. Note that no file writing happens on a failed read/setup, because the object destructor is not called in such cases (only the destructors of members). The constructor takes a 'writeback' parameter (the initial value for that flag; it's left as a public member because it's really part of the object's interface) and an 'exists' parameter: if 'exists' is false, the file is not looked for - this allows us to create INI files from scratch.

To access the data, the natural operator[] syntax is provided. The intent is that when you want to write a key value, it should be created automatically if it doesn't exist; but if you read a key value and don't want to change it, there should be no such creation. The operator[] of std::map provides this automatic creation. Therefore, I provide const-overloaded versions of operator[]: the const version (which would be applied for a read-only access) checks for the key's presence first, and if not found, returns a const reference to a static "empty" instance (so readers will see blank keys). The non-const version directly uses the std::map operator[] to auto-create missing keys. This way, you can add items to a non-const INIFile: the operator[] default-constructs a new value associated with the specified key, and returns a non-const reference to it, through which you can assign the intended value.

That does require that the user start with a const INIFile when trying to do read-only access, or create a const reference to an existing non-const INIFile and call through that.
*/
